package com.apes.hr.salary.rewardPunish.service;


import com.apes.framework.api.DomainService;
import com.apes.framework.jpa.generator.service.SequenceService;
import com.apes.framework.plugin.esb.api.SimpleRequest;
import com.apes.framework.plugin.mq.MQUtil;
import com.apes.framework.util.MapUtil;
import com.apes.hr.base.model.Employee;
import com.apes.hr.base.model.TransferRecord;
import com.apes.hr.base.model.WorkPost;
import com.apes.hr.base.repository.EmployeeRepository;
import com.apes.hr.base.repository.TransferRecordRepository;
import com.apes.hr.salary.rewardPunish.model.*;
import com.apes.hr.salary.rewardPunish.repository.RewardPunishRepository;
import com.apes.hr.salary.rewardPunish.repository.TeamRewardPunishDistributionRepository;
import com.apes.hr.salary.rewardPunish.repository.TeamRewardPunishPreRepository;
import com.apes.hr.salary.rewardPunish.repository.TeamRewardPunishRepository;
import com.apes.scm.masterdata.frame.model.Branch;
import com.apes.scm.rbac.model.Post;
import com.apes.scm.rbac.repository.PostRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.stereotype.Service;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * 功能：集体奖惩记录单服务
 *
 * @author linwz
 * @create 2019-02-27 09:55
 */
@Service("teamRewardPunishService")
public class TeamRewardPunishService extends DomainService {

    @Autowired
    TeamRewardPunishRepository teamRewardPunishRepository;
    @Autowired
    EmployeeRepository employeeRepository;
    @Autowired
    PostRepository postRepository;
    @Autowired
    TeamRewardPunishItemService teamRewardPunishItemService;
    @Autowired
    TransferRecordRepository transferRecordRepository;
    @Autowired
    SequenceService sequenceService;
    @Autowired
    RewardPunishRepository rewardPunishRepository;
    @Autowired
    TeamRewardPunishPreRepository teamRewardPunishPreRepository;
    @Autowired
    TeamRewardPunishPreService teamRewardPunishPreService;
    @Autowired
    TeamRewardPunishDistributionRepository teamRewardPunishDistributionRepository;

    /**
     * 功能：保存集体奖惩记录单
     * @param request
     * @return
     */
    public TeamRewardPunish save(SimpleRequest request) {
        TeamRewardPunish teamRewardPunish = request.getO(TeamRewardPunish.class);
        teamRewardPunish.setState("create");
        if(teamRewardPunish.getId() == null){
            String code = sequenceService.getId("hr_Reward_Punish");
            teamRewardPunish.setId(code);
        }
        Post post = postRepository.findOne(request.getPostId());
        teamRewardPunish.setCompany(post.getCompany());
        teamRewardPunish.setDept(post.getDept());
        return teamRewardPunishRepository.saveAndFlush(teamRewardPunish);
    }

    /**
     * 功能：检查数据
     * @param request
     */
    public TeamRewardPunish checkData(SimpleRequest request){
        String id = request.get("id");
        int version = request.get("version");

        TeamRewardPunish oldBill = teamRewardPunishRepository.findOne(id);
        if (oldBill == null) throw new RuntimeException("奖惩记录：" + request.get("id") + " 在系统中不存在。");
        if (oldBill.getVersion() != version ) throw new RuntimeException("记录已更新或已删除，请重新提交！");

        return oldBill;
    }

    /**
     * 功能：修改数据
     * @param request
     * @return
     */
    public TeamRewardPunish update(SimpleRequest request){
        TeamRewardPunish oldBill = checkData(request);
        return save(request);
    }

    /**
     * 功能：删除奖惩记录
     * @param request
     * @return
     */
    public String delete(SimpleRequest request) {
        TeamRewardPunish oldBill = checkData(request);
        if (oldBill.getApproveDate() != null) throw new RuntimeException("奖惩记录：" + request.get("id") + " 在系统中已审批。");

        oldBill.setState("delete");
        teamRewardPunishRepository.saveAndFlush(oldBill);
        return "删除成功！";
    }

    /**
     * 功能：审核奖惩记录
     *
     * @param request
     * @return
     */
    public TeamRewardPunish approve(SimpleRequest request) {
        TeamRewardPunish oldBill = checkData(request);
        if (oldBill.getApproveDate() != null) throw new RuntimeException("奖惩记录：" + request.get("id") + " 在系统中已审核。");
        TeamRewardPunish teamRewardPunish = request.getO(TeamRewardPunish.class);
        teamRewardPunish.setState("approve");
        teamRewardPunish.setApproveDate(new Date());
        teamRewardPunish.setApproveUid(this.getPerson(request));
//        setTeamrewardItem(teamRewardPunish.getTeamRewardPunishItems(),teamRewardPunish);
        teamRewardPunish = teamRewardPunishRepository.saveAndFlush(teamRewardPunish);
//        List<Map> mapList = new ArrayList<>();
        Map<String ,String> map=new HashMap<>() ;
        map.put("teamRewardPunish_id",teamRewardPunish.getId());
        invoke("hr.teamRewardPunish.setTeamrewardItem",map);
        return teamRewardPunish;
    }

    /**
     * 功能：确定完成分配奖惩记录
     *
     * @param request
     * @return
     */
    public TeamRewardPunish allocated(SimpleRequest request) {
        TeamRewardPunish oldBill = checkData(request);
        TeamRewardPunish rewardPunish = request.getO(TeamRewardPunish.class);
        rewardPunish = teamRewardPunishRepository.findOne(rewardPunish.getId());
        List<TeamRewardPunishPre> teamRewardPunishPreList = teamRewardPunishPreRepository.findByTeamRewardPunish(rewardPunish);
        teamRewardPunishPreList = teamRewardPunishPreList.stream().filter(teamRewardPunishPre -> !teamRewardPunishPre.isDistribution()).collect(Collectors.toList());
        if (!teamRewardPunishPreList.isEmpty()){
            throw new RuntimeException("还有奖惩明细没有确定分配!");
        }
        rewardPunish.setState("allocated");
        rewardPunish = teamRewardPunishRepository.saveAndFlush(rewardPunish);
        MQUtil.publish("hr.teamRewardPunish.setRewardPunishItemTwo","集体奖惩单确认分配生成个人奖惩单", MapUtil.mapped(rewardPunish));
        return rewardPunish;
    }

    /**
     * 功能：发文奖惩记录
     *
     * @param request
     * @return
     */
    public TeamRewardPunish sendOut(SimpleRequest request) {
        TeamRewardPunish oldBill = checkData(request);
        TeamRewardPunish rewardPunish = request.getO(TeamRewardPunish.class);
        if (rewardPunish.getDocNumber()==null) throw new RuntimeException("奖惩文号不能为空");
        if (oldBill.getSendOutDate() != null) throw new RuntimeException("奖惩记录：" + request.get("id") + " 在系统中已发文。");
        rewardPunish.setState("sendOut");
        rewardPunish.setSendOutDate(new Date());
        rewardPunish.setSendOutUid(this.getPerson(request));
        if (rewardPunish.getCashDate() == null) rewardPunish.setCashDate(new Date());   //兑现时间为空设置与发文时间一致
        RewardPunish rewardPunish1 =  rewardPunishRepository.findOne(rewardPunish.getId());
        rewardPunish1.setState("sendOut");
        rewardPunish1.setDocNumber(rewardPunish.getDocNumber());
        rewardPunish1.setSendOutDate(new Date());
        rewardPunish1.setSendOutUid(this.getPerson(request));
        if (rewardPunish1.getCashDate() == null) rewardPunish1.setCashDate(rewardPunish.getCashDate());   //兑现工资所属根据集体奖惩记录的来
        rewardPunishRepository.saveAndFlush(rewardPunish1);
        return teamRewardPunishRepository.saveAndFlush(rewardPunish);
    }

    /**
     * 功能：退回奖惩记录
     * @param request
     * @return
     */
    public TeamRewardPunish sendBack(SimpleRequest request) {
        TeamRewardPunish oldBill = checkData(request);
        TeamRewardPunish teamRewardPunish = request.getO(TeamRewardPunish.class);
        if (oldBill.getSendOutDate() != null) throw new RuntimeException("奖惩记录：" + request.get("id") + " 在系统中已发文。");
        //删除集体奖惩记录分配
        teamRewardPunishDistributionRepository.deleteByTeamRewardPunishId(teamRewardPunish.getId());
        //删除集体奖惩记录前置单
        teamRewardPunishPreRepository.deleteByTeamRewardPunishId(teamRewardPunish.getId());
        teamRewardPunish.setApproveUid(null);
        teamRewardPunish.setApproveDate(null);
        teamRewardPunish.setState("create");
        return teamRewardPunishRepository.saveAndFlush(teamRewardPunish);
    }

    public TeamRewardPunish findOne(SimpleRequest request) throws Exception {
        String id = request.get("id");
        return teamRewardPunishRepository.findOne(id);
    }

    public Page<TeamRewardPunish> findOrder(SimpleRequest request){
       Post post =postRepository.findOne(request.getPostId());
       Branch  branch = post.getBranch();
       WorkPost workPost = post.getWorkPost();
       if (!workPost.getName().equals("店长")) throw new RuntimeException("此功能需店长权限！");
       return teamRewardPunishRepository.findByBranch(branch,"sendOut", PageRequest.of(request.get("page"), request.get("size")));
    }

    /**
     * 审核的同时生成集体奖惩明细单
     * @param
     */
    private void setTeamrewardItem(SimpleRequest request){
        String teamRewardPunish_id =  request.get("teamRewardPunish_id");
        TeamRewardPunish teamRewardPunish = teamRewardPunishRepository.findOne(teamRewardPunish_id);
        Set<TeamRewardPunishItem> teamRewardPunishItemSet = teamRewardPunish.getTeamRewardPunishItems();
        Set<TeamRewardPunishPre> teamRewardPunishPreSet=new HashSet<>();
        //退回后重新审核，如果已经分配的过滤掉
        teamRewardPunishItemSet = teamRewardPunishItemSet.stream().filter(item -> item.isDistribution() != true).collect(Collectors.toSet());
        teamRewardPunishItemSet.forEach(teamRewardPunishItem -> {
            Branch branch = teamRewardPunishItem.getWorkBranch();
            Date reward = teamRewardPunish.getRewardDate();
            Date end = teamRewardPunish.getRewardEndDate();
            RewardPunishType rewardPunishType = teamRewardPunish.getRewardPunishType();
            List<TransferRecord> transferRecordList1 = new ArrayList<>();
            List<TransferRecord> transferRecordList2 = new ArrayList<>();
            List<TransferRecord> newTransferRecordList = transferRecordRepository.findByWorkBranch(branch);
//            List<TransferRecord> newTransferRecordList = transferRecordRepository.findByWorkBranch(branch).stream()
//                    .filter(transferRecord -> transferRecord.getEmployee().getEmployeeState().getId().equals("000088")).collect(Collectors.toList());
            newTransferRecordList.forEach(transferRecord -> {
                if(transferRecord.getEmployee()!=null && transferRecord.getEmployee().getEmployeeState()!=null && transferRecord.getEmployee().getEmployeeState().getId().equals("000088")){
                    transferRecordList2.add(transferRecord);
                }
            });
            Map<Employee,List<TransferRecord>> empTransferList = transferRecordList2.stream().sorted(Comparator.comparing(TransferRecord::getTransferOn)).collect(Collectors.groupingBy(TransferRecord::getEmployee));

//            Map<Employee,List<TransferRecord>> empTransferList = newTransferRecordList.stream().sorted(Comparator.comparing(TransferRecord::getTransferOn)).collect(Collectors.groupingBy(TransferRecord::getEmployee));
            transferRecordList1 = teamRewardPunishItemService.screenTransfer(empTransferList,reward,end);
            List<TeamRewardPunishDistribution> distributionList = teamRewardPunishItemService.setDistribution(transferRecordList1,rewardPunishType,reward,end);
            Set<TeamRewardPunishDistribution> distributionSet= new HashSet<>() ;
            distributionList.forEach(distribution -> {
                distributionSet.add(distribution);
            });
            teamRewardPunishItem.setState("create");
            // 生成集体奖惩前置单
            teamRewardPunishPreSet.add(setTeamRewardPunishPre(teamRewardPunishItem,distributionSet));

        });
        teamRewardPunishPreSet.forEach(pre->{
            pre.setTeamRewardPunish(teamRewardPunish);
        });
    }

    public TeamRewardPunishPre setTeamRewardPunishPre(TeamRewardPunishItem item ,Set<TeamRewardPunishDistribution> distributionSet){
        TeamRewardPunishPre teamRewardPunishPre = new TeamRewardPunishPre();
        teamRewardPunishPre.setId(item.getId());
//        teamRewardPunishPre.setTeamRewardPunish(item.getTeamRewardPunish());
        teamRewardPunishPre.setWorkBranch(item.getWorkBranch());
        teamRewardPunishPre.setItemAmt(item.getItemAmt());
        teamRewardPunishPre.setItemPunishAmt(item.getItemPunishAmt());
        teamRewardPunishPre.setNoPunish(item.getNoPunish());
        teamRewardPunishPre.setDistribution(item.isDistribution());
        teamRewardPunishPre.setDistributionDate(item.getDistributionDate());
        teamRewardPunishPre.setState(item.getState());
        teamRewardPunishPre.setApproveUid(item.getApproveUid());
        teamRewardPunishPre.setApproveDate(item.getApproveDate());
        teamRewardPunishPre.setSubmitUid(item.getSubmitUid());
        teamRewardPunishPre.setSubmitDate(item.getSubmitDate());
        teamRewardPunishPre.setTeamRewardPunishDistributions(distributionSet);
        return teamRewardPunishPreRepository.saveAndFlush(teamRewardPunishPre);
    }

}
